package com.chaoyi.service;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.ibatis.session.ExecutorType;
import org.apache.ibatis.session.SqlSession;
import org.mybatis.spring.SqlSessionTemplate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.alibaba.fastjson.JSONObject;
import com.chaoyi.dao.mysql.baidumv.ChannelMapper;
import com.chaoyi.dao.mysql.baidumv.DeviceMapper;
import com.chaoyi.dao.mysql.baidumv.UserActionGroupMapper;
import com.chaoyi.dao.mysql.baidumv.UserActionVideoMapper;
import com.chaoyi.dao.mysql.baidumv.VideoMapper;
import com.chaoyi.dao.mysql.stat.ActiveUserCountMapper;
import com.chaoyi.dao.mysql.stat.ActiveUserMapper;
import com.chaoyi.dao.mysql.stat.ChannelNewUserMapper;
import com.chaoyi.dao.mysql.stat.NewUserMapper;
import com.chaoyi.dao.mysql.stat.UserActionCountMapper;
import com.chaoyi.dao.mysql.stat.UserActionMapper;
import com.chaoyi.dao.redis.RDDao;
import com.chaoyi.util.page.PageUtil;
import com.chaoyi.vo.ActiveUserStat;
import com.chaoyi.vo.Channel;
import com.chaoyi.vo.NewUserCount;
import com.chaoyi.vo.UserAction;
import com.chaoyi.vo.UserActionStat;
import com.chaoyi.vo.UserActionVideo;

@Service
public class UserActionService {
	private final Logger obtainUserActionLogger = LoggerFactory.getLogger("obtainUserActionLogger");
	private final Logger logger = LoggerFactory.getLogger(UserActionService.class);
	private final RDDao rdUserActionDao = new RDDao();
	@Autowired
	private DeviceMapper deviceMapper;
	@Autowired
	private SqlSessionTemplate sqlSessionTemplateBaiduMv;
	@Autowired
	private SqlSessionTemplate sqlSessionTemplateBaiduMvStat;	
	
	@Autowired
	private ChannelMapper channelMapper;
	@Autowired
	private UserActionGroupMapper userActionGroupMapper;
	@Autowired
	private UserActionCountMapper userActionCountMapper;
	@Autowired
	private UserActionMapper userActionMapper;
	@Autowired
	private VideoMapper videoMapper;
	@Autowired
	private UserActionVideoMapper userActionVideoMapper;
	@Autowired
	private NewUserMapper newUserMapper;
	@Autowired
	private ChannelNewUserMapper channelNewUserMapper;
	@Autowired
	private ActiveUserMapper activeUserMapper;
	@Autowired
	private ActiveUserCountMapper activeUserCountMapper;
	
	
	public void obtainUserAction(){
		String jsonStr = rdUserActionDao.brpopUserAction();
		if(jsonStr==null)
			return;
		if(obtainUserActionLogger.isInfoEnabled())
			obtainUserActionLogger.info(jsonStr);
		JSONObject json = null;
		try{
			json = JSONObject.parseObject(jsonStr,JSONObject.class);
		}catch(Exception e){
			return;
		}
		UserAction userAction = UserAction.fromJSON(json);
		dealNewUser(userAction);
		dealUserCount(userAction);
		obtainUserActionGroup(userAction);
	}
	
	public void dealNewUser(UserAction userAction){
		NewUserCount newUserCount = new NewUserCount();
		newUserCount.setDeviceNo(userAction.getDeviceNo());
		newUserCount.setCreateDate(userAction.getCreateDate());
		newUserCount.setCreateTime(userAction.getCreateTime());
		if(newUserMapper.insertNewUser(newUserCount)>0){
			newUserCount.setChannelId(userAction.getChannelId());
			channelNewUserMapper.insertOrUpdate(newUserCount);
		}
	}
	
	public void dealUserCount(UserAction userAction){
		//用户行为统计
		UserActionStat userActionStat =new UserActionStat();
		userActionStat.setDeviceNo(userAction.getDeviceNo());
		userActionStat.setAction(userAction.getAction());
		userActionStat.setCreateDate(userAction.getCreateDate());
		userActionStat.setCreateTime(userAction.getCreateTime());
		userActionStat.setChannelId(userAction.getChannelId());
		if(userActionMapper.insertUserAction(userActionStat)>0){
			userActionCountMapper.insertOrUpdate(userAction);
		}
			
		//活跃用户统计
		ActiveUserStat activeUserStat=new ActiveUserStat();
		activeUserStat.setDeviceNo(userAction.getDeviceNo());
		activeUserStat.setChannelId(userAction.getChannelId());
		activeUserStat.setCreateDate(userAction.getCreateDate());
		activeUserStat.setUserCount(1);
		if(activeUserMapper.insertActiveUser(activeUserStat)>0){
			activeUserCountMapper.insertOrUpdate(activeUserStat);
		}
	}
	
	public void obtainUserActionGroup(UserAction userAction){
		UserActionVideo userActionVideo = new UserActionVideo();
		int videoId = userAction.getVideoId();
		if(userAction.getVideoId() > 0){
			String videoClassifyName = videoMapper.selectVideoClassifyName(videoId);
			if(videoClassifyName==null){
				videoClassifyName = "";
			}
			userActionVideo.setVideoClassifyName(videoClassifyName);
			userActionVideo.setVideoId(videoId);
			userActionVideo.setDeviceNo(userAction.getDeviceNo());
			userActionVideo.setCreateTime(userAction.getCreateTime());
			userActionVideo.setCreateDate(userAction.getCreateDate());
			userActionVideo.setAction(userAction.getAction());
			userActionVideoMapper.insertVideo(userActionVideo);
		}
	}
	
	
	
	public void userActionGroupStat(String startTime,String endTime){
		logger.info("开始统计useraction startTime="+startTime+" endTime="+endTime);
		List<Channel> channelList = channelMapper.getChannelList();
		Map<String,Channel> channelMap = new HashMap<String,Channel>();
		for(Channel channel:channelList ){
			channelMap.put(channel.getChannelId(), channel);
		}
		List<UserActionStat> list = userActionGroupMapper.selectUserCount(startTime, endTime);
		SqlSession sqlSession = null;
		try {
			sqlSession = sqlSessionTemplateBaiduMv.getSqlSessionFactory().openSession(ExecutorType.BATCH, false);
			for(UserActionStat vo:list){
				Channel channel = channelMap.get(vo.getChannelId());
				if(channel!=null)
					vo.setCompanyId(channel.getCompanyId());
				sqlSession.insert("com.chaoyi.dao.mysql.baidumv.UserActionStatMapper.insertUserActionStat",vo);
			}
			sqlSession.commit();
		} catch(Exception e){
			sqlSession.rollback();
			throw e;
		} finally{
			if(sqlSession!=null){
				sqlSession.clearCache();
				sqlSession.close();
			}
		}
		list = userActionGroupMapper.selectActiveUserCount(startTime, endTime);
		try {
			sqlSession = sqlSessionTemplateBaiduMv.getSqlSessionFactory().openSession(ExecutorType.BATCH, false);
			for(UserActionStat vo:list){
				vo.setAction(-1);
				Channel channel = channelMap.get(vo.getChannelId());
				if(channel!=null)
					vo.setCompanyId(channel.getCompanyId());
				sqlSession.insert("com.chaoyi.dao.mysql.baidumv.UserActionStatMapper.insertUserActionStat",vo);
			}
			sqlSession.commit();
		} catch(Exception e){
			sqlSession.rollback();
			throw e;
		} finally{
			if(sqlSession!=null){
				sqlSession.clearCache();
				sqlSession.close();
			}
		}
	}
	
	public void transforDevice(String startDate,String endDate){
		logger.info("开始处理device数据，startDate="+startDate+" endDate="+endDate);
		int totalRecords = deviceMapper.selectTotalRecords(startDate, endDate);
		if(totalRecords==0){
			return;
		}
		int pageSize = 3000;
		int pageCount = PageUtil.getTotalPage(pageSize, totalRecords);
		Map<String,NewUserCount> map = new HashMap<String,NewUserCount>();
		for(int page=1;page<=pageCount;page++){
			List<UserAction> list = deviceMapper.selectDevice(startDate, endDate, PageUtil.getOffset(page, pageSize), pageSize);
			for(UserAction userAction:list){
				NewUserCount newUserCount = new NewUserCount();
				newUserCount.setDeviceNo(userAction.getDeviceNo());
				newUserCount.setCreateDate(userAction.getCreateDate());
				newUserCount.setCreateTime(userAction.getCreateTime());
				if(newUserMapper.insertNewUser(newUserCount)>0){
					newUserCount.setChannelId(userAction.getChannelId());
					NewUserCount current = map.get(newUserCount.getChannelId());
					if(current==null){
						current = newUserCount;
						current.setNewUserCount(1);
						map.put(current.getChannelId(), current);
					}else{
						current.setNewUserCount(current.getNewUserCount()+1);
					}
					
				}
			}
		}
		for(NewUserCount newUserCount:map.values()){
			channelNewUserMapper.insert(newUserCount);
		}
		logger.info("处理完成");
	}
	
	public List<UserActionStat> selectUserAction(){
		SqlSession sqlSession = null;
		sqlSession = sqlSessionTemplateBaiduMv.getSqlSessionFactory().openSession(ExecutorType.BATCH, false);
		List<UserActionStat> list = sqlSession.selectList("com.chaoyi.dao.mysql.baidumv.UserActionStatMapper.selectUserActionStat");
		return list;
	}
	
	public void insertActiveUserCount(UserActionStat userActionStat){
		activeUserCountMapper.insertActiveUserCount(userActionStat);
	}
	public void insertUserActionCount(UserActionStat userActionStat){
		userActionCountMapper.insertUserActionCount(userActionStat);
	}	
	public List<UserAction> selectUserActionGroup(String startTime,String endTime){
		List<UserAction> list = userActionGroupMapper.selectUserActionGroup(startTime, endTime);
		return list;
	}
	
}
